home *** CD-ROM | disk | FTP | other *** search
- //: C19:Getmem.h
- // From Thinking in C++, 2nd Edition
- // Available at http://www.BruceEckel.com
- // (c) Bruce Eckel 1999
- // Copyright notice in Copyright.txt
- // Function template for memory
- #ifndef GETMEM_H
- #define GETMEM_H
- #include "../require.h"
- #include <cstdlib>
- #include <cstring>
-
- template<class T>
- void getmem(T*& oldmem, int elems) {
- typedef int cntr; // Type of element counter
- const int csz = sizeof(cntr); // And size
- const int tsz = sizeof(T);
- if(elems == 0) {
- free(&(((cntr*)oldmem)[-1]));
- return;
- }
- T* p = oldmem;
- cntr oldcount = 0;
- if(p) { // Previously allocated memory
- // Old style:
- // ((cntr*)p)--; // Back up by one cntr
- // New style:
- cntr* tmp = reinterpret_cast<cntr*>(p);
- p = reinterpret_cast<T*>(--tmp);
- oldcount = *(cntr*)p; // Previous # elems
- }
- T* m = (T*)realloc(p, elems * tsz + csz);
- require(m != 0);
- *((cntr*)m) = elems; // Keep track of count
- const cntr increment = elems - oldcount;
- if(increment > 0) {
- // Starting address of data:
- long startadr = (long)&(m[oldcount]);
- startadr += csz;
- // Zero the additional new memory:
- memset((void*)startadr, 0, increment * tsz);
- }
- // Return the address beyond the count:
- oldmem = (T*)&(((cntr*)m)[1]);
- }
-
- template<class T>
- inline void freemem(T * m) { getmem(m, 0); }
-
- #endif // GETMEM_H ///:~
-